// 版权所有2009 Go作者。版权所有。
// 此源代码的使用受BSD样式
// 许可证的约束，该许可证可以在许可证文件中找到。

// 包时间提供测量和显示时间的功能。
// 
// 历法计算始终采用公历，
// 无闰秒。
// 
// 单调时钟
// 
// 操作系统提供了一个“挂钟”，该挂钟受
// 时钟同步更改的约束，而“单调时钟”则不是。一般的规则是墙上的钟是用来报时的，而单调的钟是用来计时的。
// 在这个包中不是拆分API，而是时间返回的时间。现在包含一个墙壁
// 时钟读数和一个单调时钟读数；后面的时间告诉
// 操作使用挂钟读数，但是后面的时间测量
// 操作，特别是比较和减法，使用
// 单调时钟读数。
// 
// 例如，此代码始终计算
// 大约20毫秒的正运行时间，即使在
// 期间更改了墙上的时钟。正在计时的操作：
// 
// 开始：=时间。现在（）
// /。。。需要20毫秒的操作。。。
// t:=time.Now（）
// appeased:=t.Sub（start）
// 
// 其他习惯用法，如time.Since（start）、time.Until（deadline）和
// 重置具有类似的鲁棒性。
// 
// 本节其余部分提供了操作
// 如何使用单调时钟的精确细节，但使用此软件包不需要了解这些细节。
// 
// 时间返回的时间。现在包含一个单调的时钟读数。
// 如果时间t具有单调时钟读数，则t.Add将相同的持续时间添加到
// 墙上的时钟和单调时钟读数以计算结果。因为t.AddDate（y，m，d）、t.Round（d）和t.Truncate（d）都是壁时计算，所以它们总是从结果中去掉任何单调的时钟读数。
// 因为t.In、t.Local和t.UTC用于解释墙壁时间
// 的效果，所以它们也会从结果中去除任何单调的时钟读数。
// 去除单调时钟读数的标准方法是使用t=t.Round（0）。
// 
// 如果时间t和u都包含单调的时钟读数，则操作
// t.After（u）、t.Before（u）、t.Equal（u）和t.Sub（u）仅使用单调的时钟读数，忽略挂钟
// 读数。如果t或u不包含单调时钟读数，则这些
// 操作将退回到使用墙上的时钟读数。
// 
// 在某些系统上，如果计算机进入睡眠状态，单调的时钟将停止。
// 在这种系统上，t.Sub（u）可能无法准确反映t和u之间经过的实际
// 时间。
// 
// 由于单调的时钟读取在当前进程之外没有任何意义，所以由t.GobEncode、
// t.MarshalBinary、t.MarshalJSON和t.MarshalText生成的序列化表单忽略了单调的
// 时钟读取，而t.Format则不提供任何格式。类似地，
// 构造函数包含time.Date、time.Parse、time.ParseInLocation和time.Unix、
// 以及解组器t.GobDecode、t.unmarshalbary。
// t.UnmarshalJSON和t.UnmarshalText始终使用
// /无单调时钟读数创建时间。
// 
// 请注意，Go==运算符不仅比较时间瞬间，还比较位置和单调时钟读数。有关相等性的讨论，请参见
// 时间类型文档
// 测试时间值。
// 
// 对于调试，t.String的结果不包括单调的
// 时钟读数（如果存在）。如果t！=由于不同的单调时钟读数，
// 在打印t.String（）和u.String（）时可以看到这种差异。
// 
package time

import (
	"errors"
	_ "unsafe" // 对于go:linkname 
)

// 时间以纳秒精度表示时间中的一个瞬间。
// 
// 使用时间的程序通常应将时间作为值存储和传递，而不是指针。也就是说，时间变量和结构字段应该是
// 类型time.time，而不是*time.time。
// 
// 除
// 方法GODECODE、UnmarshalBinary、UnmarshalJSON和
// UnmarshalText不是并发安全的外，时间值可由多个GOROUTION同时使用。
// 
// 可以使用Before、After和Equal方法比较时间实例。
// 子方法减去两个瞬间，产生一个持续时间。
// Add方法添加时间和持续时间，生成时间。
// 
// 类型时间的零值为1年1月1日00:00:00.000000000 UTC。
// 由于这一时间在实践中不太可能出现，IsZero方法为
// 提供了一种检测未显式初始化的时间的简单方法。
// 
// 每次都有与其关联的一个位置，在计算
// 时间的表示形式时参考，如格式、小时和年方法。
// 方法本地、UTC，并返回一个特定位置的时间。
// 以这种方式更改位置只会更改演示文稿；它不会改变所表示的瞬间，因此不会影响前面段落中描述的计算。
// 
// 由GobEncode、MarshalBinary、
// MarshalJSON和MarshalText方法保存的时间值的表示形式存储时间。位置的偏移量，而不是
// 位置名称。因此，它们会丢失有关夏令时的信息。
// 
// 除了所需的“挂钟”读数外，时间还可以包含可选的
// 当前进程的单调时钟读数，以提供额外的精度
// 用于比较或减法。
// 有关详细信息，请参阅软件包文档中的“单调时钟”部分。
// 
// 请注意，Go==运算符不仅比较时间瞬间，还比较
// 位置和单调时钟读数。因此，如果没有首先保证为所有值设置了相同的位置，则时间值不能用作映射或数据库键，这可以通过使用UTC或本地方法实现，通过设置t=t.Round（0），读取
// 的单调时钟已被去除。一般来说，首选t.Equal（u）
// 而不是t==u，因为t.Equal使用了最精确的比较，并且
// 正确地处理了只有一个参数具有单调时钟读数的情况。
// 
type Time struct {
	// 墙和ext编码墙时间秒、墙时间纳秒、
	// 和可选的单调时钟读数纳秒。
	// 
	// 从高位到低位，wall编码1位标志（hasMonotonic）、
	// 33位秒字段和30位wall时间纳秒字段。
	// 纳秒字段在[09999999]范围内。
	// 如果hasMonotonic位为0，则33位字段必须为零
	// 并且自1月1日起的全签名64位墙秒存储在ext.
	// 如果hasMonotonic位为1，则33位字段保存自1885年1月1日起的33位
	// 无签名墙秒，ext保存一个有符号的64位单调时钟读数，从进程开始算起纳秒。
	wall uint64
	ext  int64

	// loc指定应用于
	// 确定与此时间对应的分钟、小时、月、日和年
	// 的位置。
	// 零位置表示UTC。
	// 所有UTC时间都用loc==nil表示，从不用loc==&utcLoc表示。
	loc *Location
}

const (
	hasMonotonic = 1 << 63
	maxWall      = wallToInternal + (1<<33 - 1) // 2157年
	minWall      = wallToInternal               // 1885年
	nsecMask     = 1<<30 - 1
	nsecShift    = 30
)

// 这些用于操纵墙壁和单调时钟读数的助手
// 使用指针接收器，即使它们不修改时间，
// 也可以让它们更便宜地通话。

// nsec返回时间的纳秒数。
func (t *Time) nsec() int32 {
	return int32(t.wall & nsecMask)
}

// 秒返回自1年1月1日起的时间秒数。
func (t *Time) sec() int64 {
	if t.wall&hasMonotonic != 0 {
		return wallToInternal + int64(t.wall<<1>>(nsecShift+1))
	}
	return t.ext
}

// unixSec返回自1970年1月1日（Unix时间）以来的时间秒数。
func (t *Time) unixSec() int64 { return t.sec() + internalToUnix }

// addSec将时间加上d秒。
func (t *Time) addSec(d int64) {
	if t.wall&hasMonotonic != 0 {
		sec := int64(t.wall << 1 >> (nsecShift + 1))
		dsec := sec + d
		if 0 <= dsec && dsec <= 1<<33-1 {
			t.wall = t.wall&nsecMask | uint64(dsec)<<nsecShift | hasMonotonic
			return
		}
		// 墙秒现在超出压缩字段的范围。
		// 转到分机
		t.stripMono()
	}

	// 检查t.ext和d之和是否溢出并正确处理。
	sum := t.ext + d
	if (sum > t.ext) == (d > 0) {
		t.ext = sum
	} else if d > 0 {
		t.ext = 1<<63 - 1
	} else {
		t.ext = -(1<<63 - 1)
	}
}

// setLoc设置与时间关联的位置。
func (t *Time) setLoc(loc *Location) {
	if loc == &utcLoc {
		loc = nil
	}
	t.stripMono()
	t.loc = loc
}

// stripMono去除t中的单调时钟读数。
func (t *Time) stripMono() {
	if t.wall&hasMonotonic != 0 {
		t.ext = t.sec()
		t.wall &= nsecMask
	}
}

// setMono设置t中的单调时钟读数。
// 如果t不能保持单调的时钟读数，
// 因为它的壁时间太大，
// setMono是不可操作的。
func (t *Time) setMono(m int64) {
	if t.wall&hasMonotonic == 0 {
		sec := t.ext
		if sec < minWall || maxWall < sec {
			return
		}
		t.wall |= hasMonotonic | uint64(sec-minWall)<<nsecShift
	}
	t.ext = m
}

// mono返回t的单调时钟读数。
// 对于缺少的读数，返回0。
// 此函数仅用于测试，
// 因此，从技术上讲，0是一个有效的
// 单调时钟读数也是可以的。
func (t *Time) mono() int64 {
	if t.wall&hasMonotonic == 0 {
		return 0
	}
	return t.ext
}

// After报告时间瞬间t是否在u之后。
func (t Time) After(u Time) bool {
	if t.wall&u.wall&hasMonotonic != 0 {
		return t.ext > u.ext
	}
	ts := t.sec()
	us := u.sec()
	return ts > us || ts == us && t.nsec() > u.nsec()
}

// Before报告时间瞬间t是否在u之前。
func (t Time) Before(u Time) bool {
	if t.wall&u.wall&hasMonotonic != 0 {
		return t.ext < u.ext
	}
	ts := t.sec()
	us := u.sec()
	return ts < us || ts == us && t.nsec() < u.nsec()
}

// 相等报告t和u是否代表同一时间瞬间。
// 即使在不同的位置，两次也可以相等。
// 例如，协调世界时6:00+0200和4:00是相等的。
// 有关使用==和
// 时间值的陷阱，请参阅有关时间类型的文档；大多数代码应该使用Equal。
func (t Time) Equal(u Time) bool {
	if t.wall&u.wall&hasMonotonic != 0 {
		return t.ext == u.ext
	}
	return t.sec() == u.sec() && t.nsec() == u.nsec()
}

// 一个月指定一年中的一个月（一月=1，…）。
type Month int

const (
	January Month = 1 + iota
	February
	March
	April
	May
	June
	July
	August
	September
	October
	November
	December
)

// 字符串返回月份的英文名称（“一月”、“二月”、“月”）。
func (m Month) String() string {
	if January <= m && m <= December {
		return longMonthNames[m-1]
	}
	buf := make([]byte, 20)
	n := fmtInt(buf, uint64(m))
	return "%!Month(" + string(buf[n:]) + ")"
}

// 工作日指定一周中的一天（星期日=0，…）。
type Weekday int

const (
	Sunday Weekday = iota
	Monday
	Tuesday
	Wednesday
	Thursday
	Friday
	Saturday
)

// String返回当天的英文名称（“星期日”、“星期一”和…）。
func (d Weekday) String() string {
	if Sunday <= d && d <= Saturday {
		return longDayNames[d]
	}
	buf := make([]byte, 20)
	n := fmtInt(buf, uint64(d))
	return "%!Weekday(" + string(buf[n:]) + ")"
}

// 按时计算。
// 
// 时间的零值定义为
// 1年1月1日00:00:00.000000000 UTC 
// 哪个（1）看起来像零，或者在日期
// （1-1-00:00 UTC），（2）在实践中不太可能出现
// 成为一个合适的“未设置”哨兵，不像1970年1月1日，并且（3）即使在UTC以西的时区，也有一个
// 非负年份，不像1-1-0 
// 00:00 UTC，在纽约是12-31-（-1）19:00:00。
// 
// 零时间值不强制时间的特定历元
// 表示。例如，为了在内部使用Unix epoch，我们可以定义它来区分1970年1月1日的零值，时间将由sec=-1，nsec=1e9表示。但是，它确实提出了一种表示，即使用1-1-1 00:00:00 UTC作为
// 历元，这就是我们所做的。
// 
// 加法和子计算不考虑历元的选择。
// 
// 表示计算-年、月、分钟等-所有
// 严重依赖正常数的除法和模。对于
// 日历计算，我们希望这些除法向下舍入，甚至
// 对于负值，因此余数始终为正值，但
// Go除法（与大多数硬件除法指令一样）舍入为
// 零。我们仍然可以进行这些计算，然后调整结果
// 为负分子，但是一遍又一遍地写调整值
// 很烦人。相反，我们可以改变到一个不同的时代，只要我们关心的时间都是积极的，然后将
// 四舍五入为零，再向下四舍五入。这些表示例程已经
// 必须添加区域偏移量，因此将翻译添加到
// 替换历元是便宜的。例如，有一个非负时间t表示我们可以写
// 
// sec=t%60 
// 
// 而不是
// 
// sec=t%60 
// 如果sec<0{
// sec}=60 
// 
// 日历以精确的400年周期运行：为1970-2369年打印的400年日历
// 也适用于2370-2769。即使是本周
// 的日子也会相配。选择
// 循环边界简化了计算，因此异常年份总是尽可能延迟为
// 长度。这意味着选择一个等于400模的年份，因此第一个闰年是第四年，第一个错过的闰年是第100年，错过的闰年是第400年。
// 因此我们更愿意打印2001-2400年的日历，并将其重新用于2401-2800年。
// 
// 最后，如果Unix纪元和
// 很久以前的纪元之间的增量可以用int64常量表示，这是很方便的。
// 
// 这三个考虑因素尽可能早地选择一个时代，即
// 使用一年等于1 mod 400，不超过2⁶3秒
// 早于1970年，我们来到了公元29227702299年。我们将今年的
// 称为绝对零年，将今年以来以uint64 
// 秒计量的时间称为绝对时间。
// 
// 从1年开始以int64秒为单位测量的时间-用于时间的秒字段的表示形式
// 称为内部时间。
// 
// 自1970年以来以整数64秒计算的时间称为Unix 
// 时间。
// 
// 很容易将第一年作为绝对纪元，定义
// 例程仅在>=1年内有效。但是，当在UTC以西的时区显示历元时，
// 例程将无效，因为它是0年。说一半的时间不支持正确打印零时间似乎站不住脚。相比之下，在
// 年份-292277022399中，有些时候处理不当是合理的。
// 
// 所有这些对API的客户端来说都是不透明的，如果
// 有更好的实现，这些都可以更改。

const (
	// 内部计算的无符号零年。
	// 必须是1 mod 400，并且在它计算不正确之前的次数，
	// 但是可以随意更改。
	absoluteZeroYear = -292277022399

	// 零时间的年份。
	// 由下面的内部单向计算假设。
	internalYear = 1

	// 在内部和绝对时间或Unix时间之间转换的偏移量。
	absoluteToInternal int64 = (absoluteZeroYear - internalYear) * 365.2425 * secondsPerDay
	internalToAbsolute       = -absoluteToInternal

	unixToInternal int64 = (1969*365 + 1969/4 - 1969/100 + 1969/400) * secondsPerDay
	internalToUnix int64 = -unixToInternal

	wallToInternal int64 = (1884*365 + 1884/4 - 1884/100 + 1884/400) * secondsPerDay
	internalToWall int64 = -wallToInternal
)

// IsZero报告t是否表示零时间瞬间，
// 1年1月1日00:00:00 UTC。
func (t Time) IsZero() bool {
	return t.sec() == 0 && t.nsec() == 0
}

// abs返回时间t作为绝对时间，由区域偏移量调整。
// 在计算表示属性（如月份或小时）时调用它。
func (t Time) abs() uint64 {
	l := t.loc
	// 尽可能避免函数调用。
	if l == nil || l == &localLoc {
		l = l.get()
	}
	sec := t.unixSec()
	if l != &utcLoc {
		if l.cacheZone != nil && l.cacheStart <= sec && sec < l.cacheEnd {
			sec += int64(l.cacheZone.offset)
		} else {
			_, offset, _, _, _ := l.lookup(sec)
			sec += int64(offset)
		}
	}
	return uint64(sec + (unixToInternal + internalToAbsolute))
}

// locabs是Zone和abs方法的组合，
// 从单个区域查找中提取两个返回值。
func (t Time) locabs() (name string, offset int, abs uint64) {
	l := t.loc
	if l == nil || l == &localLoc {
		l = l.get()
	}
	// 如果命中本地时间缓存，则避免函数调用。
	sec := t.unixSec()
	if l != &utcLoc {
		if l.cacheZone != nil && l.cacheStart <= sec && sec < l.cacheEnd {
			name = l.cacheZone.name
			offset = l.cacheZone.offset
		} else {
			name, offset, _, _, _ = l.lookup(sec)
		}
		sec += int64(offset)
	} else {
		name = "UTC"
	}
	abs = uint64(sec + (unixToInternal + internalToAbsolute))
	return
}

// Date返回t发生的年份、月份和日期。
func (t Time) Date() (year int, month Month, day int) {
	year, month, day, _ = t.date(true)
	return
}

// Year返回t发生的年份。
func (t Time) Year() int {
	year, _, _, _ := t.date(false)
	return year
}

// Month返回t指定的一年中的月份。
func (t Time) Month() Month {
	_, month, _, _ := t.date(true)
	return month
}

// Day返回t指定的月份的日期。
func (t Time) Day() int {
	_, _, day, _ := t.date(true)
	return day
}

// Weekday返回t指定的星期几。
func (t Time) Weekday() Weekday {
	return absWeekday(t.abs())
}

// ABS工作日与工作日类似，但以绝对时间运行。
func absWeekday(abs uint64) Weekday {
	// 绝对年份的1月1日，就像2001年的1月1日一样，是星期一。
	sec := (abs + uint64(Monday)*secondsPerDay) % secondsPerWeek
	return Weekday(int(sec) / secondsPerDay)
}

// ISOWeek返回t出现的ISO 8601年和周数。
// 周数范围从1到53。n年的1月1日至3日可能属于
// n-1年的第52周或53周，12月29日至12月31日可能属于n+1年的第1周
// 周。
func (t Time) ISOWeek() (year, week int) {
	// 根据规则，一个日历年的第一个日历周是
	// 包括该年第一个星期四在内的一周，最后一个是
	// 下一日历年第一个日历周的前一周。
	// 见https:

	// 周从周一开始
	// 周一周二周三周五周六周日
	// 1234567 
	// 抵销至星期四
	abs := t.abs()
	d := Thursday - absWeekday(abs)
	// handle Sunday 
	if d == 4 {
		d = -3
	}
	// 查找日历周的星期四
	abs += uint64(d) * secondsPerDay
	year, _, _, yday := absDate(abs, false)
	return year, yday/7 + 1
}

// 时钟返回t指定日期内的小时、分钟和秒。
func (t Time) Clock() (hour, min, sec int) {
	return absClock(t.abs())
}

// ABSCALL与时钟类似，但以绝对时间运行。
func absClock(abs uint64) (hour, min, sec int) {
	sec = int(abs % secondsPerDay)
	hour = sec / secondsPerHour
	sec -= hour * secondsPerHour
	min = sec / secondsPerMinute
	sec -= min * secondsPerMinute
	return
}

// Hour返回t指定日期内的小时，范围为[0,23]。
func (t Time) Hour() int {
	return int(t.abs()%secondsPerDay) / secondsPerHour
}

// Minute返回t指定的小时内的分钟偏移量，范围为[0,59]。
func (t Time) Minute() int {
	return int(t.abs()%secondsPerHour) / secondsPerMinute
}

// Second返回t指定分钟内的第二个偏移量，范围为[0,59]。
func (t Time) Second() int {
	return int(t.abs() % secondsPerMinute)
}

// 纳秒返回范围[0，99999999]内由t，
// 指定的秒内的纳秒偏移量。
func (t Time) Nanosecond() int {
	return int(t.nsec())
}

// YearDay返回t指定的一年中的某一天，对于非闰年，在[1365]范围内，
// 和[1366]闰年。
func (t Time) YearDay() int {
	_, _, _, yday := t.date(false)
	return yday + 1
}

// 持续时间表示两个瞬间之间经过的时间
// 作为int64纳秒计数。本声明将
// 可代表的最大期限限制为约290年。
type Duration int64

const (
	minDuration Duration = -1 << 63
	maxDuration Duration = 1<<63 - 1
)

// 通用持续时间。没有日或更大单位的定义
// 以避免在夏令时时区转换中出现混淆。
// 
// 要计算持续时间内的单位数，请除以：
// 秒：=时间。秒
// fmt.Print（int64（秒/时间.毫秒））
// 
// 将单位数转换为持续时间，乘法：
// 秒：=10 
// fmt.Print（time.Duration（seconds）*time.Second）
// 
const (
	Nanosecond  Duration = 1
	Microsecond          = 1000 * Nanosecond
	Millisecond          = 1000 * Microsecond
	Second               = 1000 * Millisecond
	Minute               = 60 * Second
	Hour                 = 60 * Minute
)

// 字符串返回一个表示持续时间的字符串，格式为“72h3m0.5s”。
// 省略前导零单位。作为一种特殊情况，持续时间小于1秒的
// 秒格式使用更小的单位（毫秒、微秒或纳秒），以确保
// 前导数字不为零。零持续时间格式为0。
func (d Duration) String() string {
	// 最大时间为2540400h10m10.000000000s 
	var buf [32]byte
	w := len(buf)

	u := uint64(d)
	neg := d < 0
	if neg {
		u = -u
	}

	if u < uint64(Second) {
		// 特殊情况：如果持续时间小于一秒，
		// 使用更小的单位，像1.2ms 
		var prec int
		w--
		buf[w] = 's'
		w--
		switch {
		case u == 0:
			return "0s"
		case u < uint64(Microsecond):
			// 打印纳秒
			prec = 0
			buf[w] = 'n'
		case u < uint64(Millisecond):
			// 打印微秒
			prec = 3
			// U+00B5'µ'微符号==0xC2 0xB5 
			w-- // 需要两个字节的空间。
			copy(buf[w:], "µ")
		default:
			// 打印毫秒
			prec = 6
			buf[w] = 'm'
		}
		w, u = fmtFrac(buf[:w], u, prec)
		w = fmtInt(buf[:w], u)
	} else {
		w--
		buf[w] = 's'

		w, u = fmtFrac(buf[:w], u, 9)

		// 现在是整数秒
		w = fmtInt(buf[:w], u%60)
		u /= 60

		// 现在是整数分钟
		if u > 0 {
			w--
			buf[w] = 'm'
			w = fmtInt(buf[:w], u%60)
			u /= 60

			// 现在是整数小时
			// 在小时停止，因为天的长度可以不同。
			if u > 0 {
				w--
				buf[w] = 'h'
				w = fmtInt(buf[:w], u)
			}
		}
	}

	if neg {
		w--
		buf[w] = '-'
	}

	return string(buf[w:])
}

// fmtFrac将v/10**prec（例如，“.12345”）的分数格式化为buf的
// 尾部，省略尾部的零。当分数为0时，它也省略了十进制
// 点。它返回
// 输出字节开始的索引和值v/10**prec。
func fmtFrac(buf []byte, v uint64, prec int) (nw int, nv uint64) {
	// 省略小数点以下的尾随零。
	w := len(buf)
	print := false
	for i := 0; i < prec; i++ {
		digit := v % 10
		print = print || digit != 0
		if print {
			w--
			buf[w] = byte(digit) + '0'
		}
		v /= 10
	}
	if print {
		w--
		buf[w] = '.'
	}
	return w, v
}

// fmtInt将v格式化为buf的尾部。
// 返回输出开始的索引。
func fmtInt(buf []byte, v uint64) int {
	w := len(buf)
	if v == 0 {
		w--
		buf[w] = '0'
	} else {
		for v > 0 {
			w--
			buf[w] = byte(v%10) + '0'
			v /= 10
		}
	}
	return w
}

// 纳秒将持续时间作为整数纳秒计数返回。
func (d Duration) Nanoseconds() int64 { return int64(d) }

// 微秒将持续时间作为整数微秒计数返回。
func (d Duration) Microseconds() int64 { return int64(d) / 1e3 }

// 毫秒以整数毫秒计数的形式返回持续时间。
func (d Duration) Milliseconds() int64 { return int64(d) / 1e6 }

// 这些方法返回float64，因为主要的
// 用例用于打印像1.5s这样的浮点数，而
// 截断为整数将使它们在这些情况下不再有用。
// 我们自己将整数和分数分开保证
// 将返回的float64转换为整数将使用与纯整数转换相同的方法，即使在
// 其中，例如float64（d.纳秒（））/1e9将以不同的方式对
// /进行四舍五入。

// Seconds以浮点秒数返回持续时间。
func (d Duration) Seconds() float64 {
	sec := d / Second
	nsec := d % Second
	return float64(sec) + float64(nsec)/1e9
}

// Minutes以浮点分钟数返回持续时间。
func (d Duration) Minutes() float64 {
	min := d / Minute
	nsec := d % Minute
	return float64(min) + float64(nsec)/(60*1e9)
}

// Hours以浮点小时数返回持续时间。
func (d Duration) Hours() float64 {
	hour := d / Hour
	nsec := d % Hour
	return float64(hour) + float64(nsec)/(60*60*1e9)
}

// Truncate返回将d向零舍入到m的倍数的结果。
// 如果m<=0，Truncate返回d不变。
func (d Duration) Truncate(m Duration) Duration {
	if m <= 0 {
		return d
	}
	return d - d%m
}

// lessThanHalf报告x+x是否小于y，但避免溢出，
// 假设x和y均为正（持续时间为有符号）。
func lessThanHalf(x, y Duration) bool {
	return uint64(x)+uint64(x) < uint64(y)
}

// Round返回将d四舍五入到m的最近倍数的结果。
// 中间值的舍入行为是从零开始舍入。
// 如果结果超过可存储在持续时间中的最大（或最小）值，
// 则返回最大（或最小）持续时间。
// 如果m<=0，则四舍五入返回d不变。
func (d Duration) Round(m Duration) Duration {
	if m <= 0 {
		return d
	}
	r := d % m
	if d < 0 {
		r = -r
		if lessThanHalf(r, m) {
			return d + r
		}
		if d1 := d - m + r; d1 < d {
			return d1
		}
		return minDuration // 溢出
	}
	if lessThanHalf(r, m) {
		return d - r
	}
	if d1 := d + m - r; d1 > d {
		return d1
	}
	return maxDuration // 溢出
}

// Add返回时间t+d。
func (t Time) Add(d Duration) Time {
	dsec := int64(d / 1e9)
	nsec := t.nsec() + int32(d%1e9)
	if nsec >= 1e9 {
		dsec++
		nsec -= 1e9
	} else if nsec < 0 {
		dsec--
		nsec += 1e9
	}
	t.wall = t.wall&^nsecMask | uint64(nsec) // 更新nsec 
	t.addSec(dsec)
	if t.wall&hasMonotonic != 0 {
		te := t.ext + int64(d)
		if d < 0 && te > t.ext || d > 0 && te < t.ext {
			// 单调时钟读数现在超出范围；只能降级到墙。
			t.stripMono()
		} else {
			t.ext = te
		}
	}
	return t
}

// Sub返回持续时间t-u。如果结果超过了一个持续时间中可以存储的最大（或最小）持续时间
// 值，则返回最大（或最小）持续时间
// 值。
// 要计算持续时间d的t-d，请使用t.Add（-d）。
func (t Time) Sub(u Time) Duration {
	if t.wall&u.wall&hasMonotonic != 0 {
		te := t.ext
		ue := u.ext
		d := Duration(te - ue)
		if d < 0 && te > ue {
			return maxDuration // t-u为正超出范围
		}
		if d > 0 && te < ue {
			return minDuration // t-u为负超出范围
		}
		return d
	}
	d := Duration(t.sec()-u.sec())*Second + Duration(t.nsec()-u.nsec())
	// 检查溢出或下溢。
	switch {
	case u.Add(d).Equal(t):
		return d // d是正确的
	case t.Before(u):
		return minDuration // t-u为负超出范围
	default:
		return maxDuration // t-u为正超出范围
	}
}

// Since返回从t开始经过的时间。
// 它是时间的简写。
func Since(t Time) Duration {
	var now Time
	if t.wall&hasMonotonic != 0 {
		// 常见情况优化：如果t具有单调时间，则Sub将仅使用它。
		now = Time{hasMonotonic, runtimeNano() - startNano, nil}
	} else {
		now = Now()
	}
	return now.Sub(t)
}

// till返回直到t的持续时间。
// 它是t.Sub（time.Now（））的缩写。
func Until(t Time) Duration {
	var now Time
	if t.wall&hasMonotonic != 0 {
		// 常见情况优化：如果t具有单调时间，则Sub将仅使用它。
		now = Time{hasMonotonic, runtimeNano() - startNano, nil}
	} else {
		now = Now()
	}
	return t.Sub(now)
}

// AddDate返回将
// 给定的年、月、日数添加到t中所对应的时间。
// 例如，AddDate（-1,2,3）应用于2011年1月1日
// 返回2010年3月4日。
// 
// AddDate以与Date相同的方式对其结果进行规范化，例如，将一个月添加到10月31日将产生
// 12月1日，即11月31日的规范化形式。
func (t Time) AddDate(years int, months int, days int) Time {
	year, month, day := t.Date()
	hour, min, sec := t.Clock()
	return Date(year+years, month+Month(months), day+days, hour, min, sec, int(t.nsec()), t.Location())
}

const (
	secondsPerMinute = 60
	secondsPerHour   = 60 * secondsPerMinute
	secondsPerDay    = 24 * secondsPerHour
	secondsPerWeek   = 7 * secondsPerDay
	daysPer400Years  = 365*400 + 97
	daysPer100Years  = 365*100 + 24
	daysPer4Years    = 365*4 + 1
)

// date计算一年中的日期，当full=true时，
// t出现的月份和日期。
func (t Time) date(full bool) (year int, month Month, day int, yday int) {
	return absDate(t.abs(), full)
}

// absDate与date类似，但以绝对时间运行。
func absDate(abs uint64, full bool) (year int, month Month, day int, yday int) {
	// 分为时间和日期。
	d := abs / secondsPerDay

	// 说明了400年周期。
	n := d / daysPer400Years
	y := 400 * n
	d -= daysPer400Years * n

	// 切断100年周期。
	// 最后一个周期有一个额外的闰年，因此在那一年的最后一天
	// 100年的天数将是4而不是3。
	// 通过减去n>>2将其缩减为3。
	n = d / daysPer100Years
	n -= n >> 2
	y += 100 * n
	d -= daysPer100Years * n

	// 截止4年周期。
	// 上一个周期缺少闰年，这不会影响计算。
	n = d / daysPer4Years
	y += 4 * n
	d -= daysPer4Years * n

	// 四年周期内的截止年份。最后一年是闰年，所以在那一年的最后一天，日期将由3改为4。通过减去n>>2，将其缩减为3 
	// 。
	n = d / 365
	n -= n >> 2
	y += n
	d -= 365 * n

	year = int(int64(y) + absoluteZeroYear)
	yday = int(d)

	if !full {
		return
	}

	day = yday
	if isLeap(year) {
		// 闰年
		switch {
		case day > 31+29-1:
			// 闰日后；假装它不在那里。
			day--
		case day == 31+29-1:
			// 闰日。
			month = February
			day = 29
			return
		}
	}

	// 假设每个月有31天，估计月份。
	// 估计值可能太低，最多一个月，请调整。
	month = Month(day / 31)
	end := int(daysBefore[month+1])
	var begin int
	if day >= end {
		month++
		begin = end
	} else {
		begin = int(daysBefore[month])
	}

	month++ // 因为1月是1日
	day = day - begin + 1
	return
}

// 天在[m]之前计算非闰年
// 在m月开始之前的天数。有一个m=12的条目，计算
// 明年1月之前的天数（365）。
var daysBefore = [...]int32{
	0,
	31,
	31 + 28,
	31 + 28 + 31,
	31 + 28 + 31 + 30,
	31 + 28 + 31 + 30 + 31,
	31 + 28 + 31 + 30 + 31 + 30,
	31 + 28 + 31 + 30 + 31 + 30 + 31,
	31 + 28 + 31 + 30 + 31 + 30 + 31 + 31,
	31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30,
	31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31,
	31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30,
	31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31,
}

func daysIn(m Month, year int) int {
	if m == February && isLeap(year) {
		return 29
	}
	return int(daysBefore[m] - daysBefore[m-1])
}

// daysSinceEpoch需要一年，并返回从
// 绝对历元到该年开始的天数。
// 这基本上是（年-零年）*365，但考虑到闰日。
func daysSinceEpoch(year int) uint64 {
	y := uint64(int64(year) - absoluteZeroYear)

	// 从400年周期中添加天数。
	n := y / 400
	y -= 400 * n
	d := daysPer400Years * n

	// 加上100年周期。
	n = y / 100
	y -= 100 * n
	d += daysPer100Years * n

	// 加上4年周期。
	n = y / 4
	y -= 4 * n
	d += daysPer4Years * n

	// 添加非闰年。
	n = y
	d += 365 * n

	return d
}

// 由包运行时提供。
func now() (sec int64, nsec int32, mono int64)

// runtimeNano以纳秒为单位返回运行时时钟的当前值。
// go:linkname runtimeNano runtime.nanotime 
func runtimeNano() int64

// 单调时间报告为与StartAno的偏移量。
// 我们将StartAno初始化为runtimeNano（）-1，以便在
// 单调时间分辨率相当低的系统上（例如Windows 2008 
// 其默认分辨率为15ms），
// 我们避免报告单调时间为0。
// （呼叫者可能希望使用0作为“未设置的时间”。）
var startNano int64 = runtimeNano() - 1

// 现在返回当前本地时间。
func Now() Time {
	sec, nsec, mono := now()
	mono -= startNano
	sec += unixToInternal - minWall
	if uint64(sec)>>33 != 0 {
		return Time{uint64(nsec), sec + minWall, Local}
	}
	return Time{hasMonotonic | uint64(sec)<<nsecShift | uint64(nsec), mono, Local}
}

func unixTime(sec int64, nsec int32) Time {
	return Time{uint64(nsec), sec + unixToInternal, Local}
}

// UTC返回t，位置设置为UTC。
func (t Time) UTC() Time {
	t.setLoc(&utcLoc)
	return t
}

// Local返回t，位置设置为本地时间。
func (t Time) Local() Time {
	t.setLoc(Local)
	return t
}

// In返回表示同一时间瞬间的t的副本，但
// ，副本的位置信息设置为loc以显示
// 。
// 
// 如果loc为零，则处于恐慌状态。
func (t Time) In(loc *Location) Time {
	if loc == nil {
		panic("time: missing Location in call to Time.In")
	}
	t.setLoc(loc)
	return t
}

// Location返回与t关联的时区信息。
func (t Time) Location() *Location {
	l := t.loc
	if l == nil {
		l = UTC
	}
	return l
}

// Zone计算在时间t生效的时区，返回缩写的
// 分区名称（如“CET”）及其在UTC以东的偏移量（以秒为单位）。
func (t Time) Zone() (name string, offset int) {
	name, offset, _, _, _ = t.loc.lookup(t.unixSec())
	return
}

// Unix返回t作为Unix时间，即自UTC 1970年1月1日以来经过的秒数。结果不依赖于与t关联的
// 位置。
// 类Unix操作系统通常将时间记录为32位
// 秒数，但由于此处的方法返回64位
// 值，因此它在过去或未来的数十亿年内有效。
func (t Time) Unix() int64 {
	return t.unixSec()
}

// UnixMilli返回t作为Unix时间，即自
// 1970年1月1日UTC。如果Unix时间（单位为
// 毫秒）不能用int64表示（1970年之前或之后超过2.92亿
// 年的日期），则结果未定义。结果不依赖于与t关联的
// 位置。
func (t Time) UnixMilli() int64 {
	return t.unixSec()*1e3 + int64(t.nsec())/1e6
}

// UnixMicro返回t作为Unix时间，即自
// 1970年1月1日UTC以来经过的微秒数。如果在
// 微秒中的Unix时间不能用int64表示（日期在-290307年之前或
// 在294246年之后），则结果是未定义的。结果不取决于
// 与t关联的位置。
func (t Time) UnixMicro() int64 {
	return t.unixSec()*1e6 + int64(t.nsec())/1e3
}

// UnixNano返回t作为Unix时间，表示自UTC 1970年1月1日以来经过的纳秒数。如果Unix时间
// 以纳秒为单位不能用int64（
// 1678年之前或2262年之后的日期）表示，则结果未定义。请注意，这意味着在零时间调用UnixNano 
// 的结果未定义。结果不依赖于与t关联的
// 位置。
func (t Time) UnixNano() int64 {
	return (t.unixSec())*1e9 + int64(t.nsec())
}

const timeBinaryVersion byte = 1

// MarshalBinary实现encoding.BinaryMarshaler接口。
func (t Time) MarshalBinary() ([]byte, error) {
	var offsetMin int16 // UTC以东分钟-1是UTC。

	if t.Location() == UTC {
		offsetMin = -1
	} else {
		_, offset := t.Zone()
		if offset%60 != 0 {
			return nil, errors.New("Time.MarshalBinary: zone offset has fractional minute")
		}
		offset /= 60
		if offset < -32768 || offset == -1 || offset > 32767 {
			return nil, errors.New("Time.MarshalBinary: unexpected zone offset")
		}
		offsetMin = int16(offset)
	}

	sec := t.sec()
	nsec := t.nsec()
	enc := []byte{
		timeBinaryVersion, // 字节0:版本
		byte(sec >> 56),   // 字节1-8:秒
		byte(sec >> 48),
		byte(sec >> 40),
		byte(sec >> 32),
		byte(sec >> 24),
		byte(sec >> 16),
		byte(sec >> 8),
		byte(sec),
		byte(nsec >> 24), // 字节9-12:纳秒
		byte(nsec >> 16),
		byte(nsec >> 8),
		byte(nsec),
		byte(offsetMin >> 8), // 字节13-14:以分钟为单位的区域偏移量
		byte(offsetMin),
	}

	return enc, nil
}

// 解组二进制实现encoding.BinaryUnmarshaler接口。
func (t *Time) UnmarshalBinary(data []byte) error {
	buf := data
	if len(buf) == 0 {
		return errors.New("Time.UnmarshalBinary: no data")
	}

	if buf[0] != timeBinaryVersion {
		return errors.New("Time.UnmarshalBinary: unsupported version")
	}

	if len(buf) != /*version*/ 1+ /*sec*/ 8+ /*nsec*/ 4+ /*zone offset*/ 2 {
		return errors.New("Time.UnmarshalBinary: invalid length")
	}

	buf = buf[1:]
	sec := int64(buf[7]) | int64(buf[6])<<8 | int64(buf[5])<<16 | int64(buf[4])<<24 |
		int64(buf[3])<<32 | int64(buf[2])<<40 | int64(buf[1])<<48 | int64(buf[0])<<56

	buf = buf[8:]
	nsec := int32(buf[3]) | int32(buf[2])<<8 | int32(buf[1])<<16 | int32(buf[0])<<24

	buf = buf[4:]
	offset := int(int16(buf[1])|int16(buf[0])<<8) * 60

	*t = Time{}
	t.wall = uint64(nsec)
	t.ext = sec

	if offset == -1*60 {
		t.setLoc(&utcLoc)
	} else if _, localoff, _, _, _ := Local.lookup(t.unixSec()); offset == localoff {
		t.setLoc(Local)
	} else {
		t.setLoc(FixedZone("", offset))
	}

	return nil
}

// TODO（rsc）：删除Go 2中的GobEncoder、GobDecoder、MarshalJSON、UnmarshalJSON。
// 通用MarshalBinary、MarshalText、
// UnmarshalBinary、UnmarshalText将提供相同的语义。

// GobEncode实现gob.GobEncoder接口。
func (t Time) GobEncode() ([]byte, error) {
	return t.MarshalBinary()
}

// GobDecode实现gob.GobDecode接口。
func (t *Time) GobDecode(data []byte) error {
	return t.UnmarshalBinary(data)
}

// MarshalJSON实现json.Marshaler接口。
// 时间是RFC 3339格式的带引号的字符串，如果存在，则添加亚秒精度。
func (t Time) MarshalJSON() ([]byte, error) {
	if y := t.Year(); y < 0 || y >= 10000 {
		// RFC 3339清楚地表明年份正好是4位数字。
		// 有关更多讨论，请参见golang.org/issue/4556#c15。
		return nil, errors.New("Time.MarshalJSON: year outside of range [0,9999]")
	}

	b := make([]byte, 0, len(RFC3339Nano)+2)
	b = append(b, '"')
	b = t.AppendFormat(b, RFC3339Nano)
	b = append(b, '"')
	return b, nil
}

// UnmarshalJSON实现json.Unmarshaler接口。
// 时间应为RFC 3339格式的带引号字符串。
func (t *Time) UnmarshalJSON(data []byte) error {
	// 忽略null，就像在主JSON包中一样。
	if string(data) == "null" {
		return nil
	}
	// 小数秒由Parse隐式处理。
	var err error
	*t, err = Parse(`"`+RFC3339+`"`, string(data))
	return err
}

// MarshalText实现了encoding.TextMarshaler接口。
// 时间格式为RFC 3339格式，如果存在，则添加亚秒精度。
func (t Time) MarshalText() ([]byte, error) {
	if y := t.Year(); y < 0 || y >= 10000 {
		return nil, errors.New("Time.MarshalText: year outside of range [0,9999]")
	}

	b := make([]byte, 0, len(RFC3339Nano))
	return t.AppendFormat(b, RFC3339Nano), nil
}

// UnmarshalText实现encoding.TextUnmarshaler接口。
// 预计时间为RFC 3339格式。
func (t *Time) UnmarshalText(data []byte) error {
	// 小数秒由Parse隐式处理。
	var err error
	*t, err = Parse(RFC3339, string(data))
	return err
}

// Unix返回与给定Unix时间对应的本地时间，
// 秒和nsec纳秒（自UTC 1970年1月1日起）。
// 在[099999999]范围外通过nsec是有效的。
// 并非所有秒值都有相应的时间值。其中一个
// 值为1<<63-1（最大int64值）。
func Unix(sec int64, nsec int64) Time {
	if nsec < 0 || nsec >= 1e9 {
		n := nsec / 1e9
		sec += n
		nsec -= n * 1e9
		if nsec < 0 {
			nsec += 1e9
			sec--
		}
	}
	return unixTime(sec, int32(nsec))
}

// UnixMilli返回给定Unix时间对应的本地时间，
// 自1970年1月1日UTC起毫秒。
func UnixMilli(msec int64) Time {
	return Unix(msec/1e3, (msec%1e3)*1e6)
}

// UnixMicro返回给定Unix时间对应的本地时间，
// 自UTC 1970年1月1日起使用c微秒。
func UnixMicro(usec int64) Time {
	return Unix(usec/1e6, (usec%1e6)*1e3)
}

// IsDST报告配置位置中的时间是否为夏令时。
func (t Time) IsDST() bool {
	_, _, _, _, isDST := t.loc.lookup(t.Unix())
	return isDST
}

func isLeap(year int) bool {
	return year%4 == 0 && (year%100 != 0 || year%400 == 0)
}

// norm返回nhi，nlo，使
// hi*base+lo==nhi*base+nlo 
// 0<=nlo<base 
func norm(hi, lo, base int) (nhi, nlo int) {
	if lo < 0 {
		n := (-lo-1)/base + 1
		hi -= n
		lo += n * base
	}
	if lo >= base {
		n := lo / base
		hi += n
		lo -= n * base
	}
	return hi, lo
}

// Date返回给定位置相应区域内该时间对应于
// yyyyy-mm-dd hh:mm:ss+nsec纳秒
// 。
// 
// 月、日、小时、分钟、秒和nsec值可能超出
// 其通常范围，并将在转换过程中进行标准化。
// 例如，10月32日转换为11月1日。
// 
// 夏令时转换跳过或重复时间。例如，在美国，2011年3月13日凌晨2:15从未发生过，而2011年11月6日凌晨1:15发生过两次。在这种情况下，
// 时区的选择，以及时间的定义并不明确。
// Date返回在转换过程中涉及的两个区域中的一个区域中正确的时间，但不保证正确。
// 
// 如果loc为零，则日期恐慌。
func Date(year int, month Month, day, hour, min, sec, nsec int, loc *Location) Time {
	if loc == nil {
		panic("time: missing Location in call to Date")
	}

	// 将月份正常化，溢出到年中。
	m := int(month) - 1
	year, m = norm(year, m, 12)
	month = Month(m) + 1

	// 将nsec、秒、分、时标准化，溢出到一天中。
	sec, nsec = norm(sec, nsec, 1e9)
	min, sec = norm(min, sec, 60)
	hour, min = norm(hour, min, 60)
	day, hour = norm(day, hour, 24)

	// 计算自绝对纪元起的天数。
	d := daysSinceEpoch(year)

	// 在本月前的天添加。
	d += uint64(daysBefore[month-1])
	if isLeap(year) && month >= March {
		d++ // 2月29日
	}

	// 在今天前几天添加。
	d += uint64(day - 1)

	// 今天已过加载项时间。
	abs := d * secondsPerDay
	abs += uint64(hour*secondsPerHour + min*secondsPerMinute + sec)

	unix := int64(abs) + (absoluteToInternal + internalToUnix)

	// 查找t的区域偏移量，以便我们可以调整到UTC。
	// 查找函数需要UTC，因此我们在
	// 中传递t，希望它不会太接近区域转换，
	// 如果是，则进行调整。
	_, offset, start, end, _ := loc.lookup(unix)
	if offset != 0 {
		switch utc := unix - int64(offset); {
		case utc < start:
			_, offset, _, _, _ = loc.lookup(start - 1)
		case utc >= end:
			_, offset, _, _, _ = loc.lookup(end)
		}
		unix -= int64(offset)
	}

	t := unixTime(unix, int32(nsec))
	t.setLoc(loc)
	return t
}

// Truncate返回将t四舍五入到d的倍数的结果（从零开始）。
// 如果d<=0，Truncate返回t，去除任何单调时钟读数，但在其他方面保持不变。
// 
// Truncate将时间作为自
// 零时间起的绝对持续时间进行操作；不适用于
// 时间的表示形式。因此，Truncate（Hour）可能返回一个非零
// 分钟的时间，具体取决于时间的位置。
func (t Time) Truncate(d Duration) Time {
	t.stripMono()
	if d <= 0 {
		return t
	}
	_, r := div(t, d)
	return t.Add(-r)
}

// Round将t四舍五入的结果返回到d的最近倍数（从零开始）。
// 中间值的舍入行为是向上舍入。
// 如果d<=0，则返回的圆t不包含任何单调的时钟读数，但在其他方面不变。
// 
// 自
// 零时间起，轮按时间作为绝对持续时间运行；不适用于
// 时间的表示形式。因此，根据时间的位置，Round（Hour）可能返回非零
// 分钟的时间。
func (t Time) Round(d Duration) Time {
	t.stripMono()
	if d <= 0 {
		return t
	}
	_, r := div(t, d)
	if lessThanHalf(r, d) {
		return t.Add(-r)
	}
	return t.Add(d - r)
}

// div将t除以d，返回商奇偶校验和余数。
// 我们不再使用商奇偶校验（取整到一半，而不是取整到偶数）
// 但它仍然在这里，以防我们改变主意。
func div(t Time, d Duration) (qmod2 int, r Duration) {
	neg := false
	nsec := t.nsec()
	sec := t.sec()
	if sec < 0 {
		// 对绝对值进行运算。
		neg = true
		sec = -sec
		nsec = -nsec
		if nsec < 0 {
			nsec += 1e9
			sec-- // sec>=1在--so safe 
		}
	}

	switch {
	// 特殊情况：2d除以1秒。
	case d < Second && Second%(d+d) == 0:
		qmod2 = int(nsec/int32(d)) & 1
		r = Duration(nsec % int32(d))

	// 特例：d是1秒的倍数。
	case d%Second == 0:
		d1 := int64(d / Second)
		qmod2 = int(sec/d1) & 1
		r = Duration(sec%d1)*Second + Duration(nsec)

	// 一般情况。
	// 如果应用更聪明的方法，这可能会更快，但这只是为了避免API中的特殊情况限制。
	// 没有人会关心这些案件。
	default:
		// 将纳秒计算为128位数字。
		sec := uint64(sec)
		tmp := (sec >> 32) * 1e9
		u1 := tmp >> 32
		u0 := tmp << 32
		tmp = (sec & 0xFFFFFFFF) * 1e9
		u0x, u0 := u0, u0+tmp
		if u0 < u0x {
			u1++
		}
		u0x, u0 = u0, u0+uint64(nsec)
		if u0 < u0x {
			u1++
		}

		// 通过减去r<<k以减少k来计算余数。
		// 商奇偶性是指我们是否在上一轮进行减法运算。如果输入是负数，并且不是d的精确倍数，我们计算q，r，使得q*d+r=-t 
		d1 := uint64(d)
		for d1>>63 != 1 {
			d1 <<= 1
		}
		d0 := uint64(0)
		for {
			qmod2 = 0
			if u1 > d1 || u1 == d1 && u0 >= d0 {
				qmod2 = 1
				u0x, u0 = u0, u0-d0
				if u0 > u0x {
					u1--
				}
				u1 -= d1
			}
			if d1 == 0 && d0 == uint64(d) {
				break
			}
			d0 >>= 1
			d0 |= (d1 & 1) << 63
			d1 >>= 1
		}
		r = Duration(u0)
	}

	if neg && r != 0 {
		// 但是正确的答案由-（q-1），d-r:
		// q*d+r=-t 
		// /-q*d-r=t 
		qmod2 ^= 1
		r = d - r
	}
	return
}
